package com.legal.service.practice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.legal.domain.po.PracticeRecord;
import com.legal.domain.po.UserPracticeStats;
import com.legal.mapper.practice.UserPracticeStatsMapper;
import com.legal.service.practice.IUserPracticeStatsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户刷题统计表 服务实现类
 * </p>
 *
 * @author xiaopeng
 * @since 2025-06-27
 */
@Service
public class UserPracticeStatsServiceImpl extends ServiceImpl<UserPracticeStatsMapper, UserPracticeStats> implements IUserPracticeStatsService {

    /**
     * 更新用户刷题统计
     *
     * @param userNo
     * @param categoryNo
     * @param record
     */
    @Override
    public void updateUserPracticeStats(String userNo, String categoryNo, PracticeRecord record) {
        // 1. 查询现有的用户刷题统计数据
        LambdaQueryWrapper<UserPracticeStats> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPracticeStats::getUserNo, userNo)
                .eq(UserPracticeStats::getCategoryNo, categoryNo);
        UserPracticeStats stats = this.getOne(queryWrapper);

        // 2. 如果不存在统计记录，则创建新的
        if (stats == null) {
            stats = new UserPracticeStats()
                    .setUserNo(userNo)
                    .setCategoryNo(categoryNo)
                    .setTotalPractices(0)
                    .setTotalQuestions(0)
                    .setCorrectCount(0)
                    .setHighestScore(BigDecimal.ZERO)
                    .setAverageScore(BigDecimal.ZERO);
        }

        // 3. 更新统计信息
        // 总刷题次数 +1
        stats.setTotalPractices(stats.getTotalPractices() + 1);

        // 总答题数增加本次答题数
        stats.setTotalQuestions(stats.getTotalQuestions() + record.getTotalQuestions());

        // 总正确数增加本次正确数
        stats.setCorrectCount(stats.getCorrectCount() + record.getCorrectCount());

        // 更新最高得分（取本次得分和原最高得分的较大值）
        if (record.getScore().compareTo(stats.getHighestScore()) > 0) {
            stats.setHighestScore(record.getScore());
        }

        // 计算新的平均得分（总得分/总刷题次数）
        BigDecimal totalScore = stats.getAverageScore() //  原平均得分 * (现在的总刷题次数-1)
                .multiply(new BigDecimal(stats.getTotalPractices() - 1)) // 总的刷题次数上面已经加1，所以这里减1
                .add(record.getScore()); // 添加上新的得分
        stats.setAverageScore(totalScore.divide( // 总分数/总刷题次数
                new BigDecimal(stats.getTotalPractices()),
                2, RoundingMode.HALF_UP));

        // 更新最后刷题时间
        stats.setLastPracticeTime(record.getEndTime());
        stats.setUpdateTime(LocalDateTime.now());

        // 4. 保存或更新统计记录
        this.saveOrUpdate(stats);
    }

    /**
     * 统计最近30天的最热题库分类（根据刷题总次数字段 total_practices）
     *
     * @return 最热门的题库分类编号列表
     */
    @Override
    public List<String> getHotCategoryNo() {
        //优化版本（直接使用SQL查询，效率更高）：
        // 直接使用SQL查询，效率更高
        QueryWrapper<UserPracticeStats> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("category_no, SUM(total_practices) as total")
                .ge("last_practice_time", LocalDateTime.now().minusDays(30))
                .groupBy("category_no")
                .orderByDesc("total")
                .last("LIMIT 5"); // 取前5个最热门分类

        return this.list(queryWrapper).stream()
                .map(UserPracticeStats::getCategoryNo)
                .collect(Collectors.toList());

      /*  // 1. 计算30天前的日期
        LocalDateTime thirtyDaysAgo = LocalDateTime.now().minusDays(30);

        // 2. 构建查询条件：最后刷题时间在30天内
        LambdaQueryWrapper<UserPracticeStats> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(UserPracticeStats::getLastPracticeTime, thirtyDaysAgo)
                .orderByDesc(UserPracticeStats::getTotalPractices);

        // 3. 查询并分组统计
        List<UserPracticeStats> statsList = this.list(queryWrapper);

        // 4. 按分类分组并计算总刷题次数
        Map<String, Integer> categoryPracticeCount = statsList.stream()
                .collect(Collectors.groupingBy(
                        UserPracticeStats::getCategoryNo,
                        Collectors.summingInt(UserPracticeStats::getTotalPractices)
                ));

        // 5. 按刷题次数排序并返回前N个分类编号
        return categoryPracticeCount.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());*/
    }
}
